package com.module.ble.widget

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.DashPathEffect
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.graphics.Shader
import android.util.AttributeSet
import android.view.View
import com.common.base.app.extras.dp2px
import com.module.ble.data.bean.SleepChartValueData

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：22/5/2025
 *
 * 描述：
 *
 * 修订历史：
 *
 */
class SleepChartView(context: Context, attrs: AttributeSet?=null) : View(context, attrs) {
    private var mDataList: List<SleepChartValueData> = arrayListOf()
    private var mWidthPixels = 0f // 屏幕的宽高
    private var mHeightPixels = 0f
    private var mTotalTime = 100f
    private var width = 0 // view 的 整体宽度和高度
    private var height = 0
    private var mViewWidth = 0 // 图标可用的宽度 -- 除去下方虚线 和 右侧竖线
    private var mViewHeight = 0
    private val leftPadding = 5
    private val rightPadding = 10
    private val topPadding = 30
    private val bottomPadding = 15
    private var elementHeight = 20 // 单独的标识的高度
    private var elementLineHeight = 30
    private val mMainPaint = Paint()
    private val mLinePaint = Paint()
    private val mVerticalLinePaint = Paint()
    private val mDashPathEffectLinePaint = Paint()
    var roundRectR = dp2px(2f) //圆角角度
    private var currDrawLeftPoint = leftPadding.toFloat()

    init {
        mWidthPixels = resources.displayMetrics.widthPixels.toFloat()
        mHeightPixels = resources.displayMetrics.heightPixels.toFloat()
        mMainPaint.style = Paint.Style.FILL_AND_STROKE
        mMainPaint.strokeWidth = 5f
        mMainPaint.isAntiAlias = true
        //        mMainPaint.setColor(Color.parseColor("#A374F7"));
        mLinePaint.style = Paint.Style.STROKE
        mLinePaint.strokeWidth = 5f
        mLinePaint.isAntiAlias = true
        mLinePaint.color = Color.parseColor("#A374F7")
        mVerticalLinePaint.style = Paint.Style.STROKE
        mVerticalLinePaint.strokeWidth = dp2px(2f)
        mVerticalLinePaint.isAntiAlias = true
        mVerticalLinePaint.color = Color.parseColor("#CDE4E4")
        mDashPathEffectLinePaint.style = Paint.Style.STROKE
        mDashPathEffectLinePaint.strokeWidth = dp2px(2f)
        mDashPathEffectLinePaint.isAntiAlias = true
        mDashPathEffectLinePaint.color = Color.parseColor("#806AA544")
        mDashPathEffectLinePaint.pathEffect =
            DashPathEffect(floatArrayOf(12f, 10f), 0f)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)
        var measuredWidth = width
        var measuredHeight = height
        if (widthMode != MeasureSpec.EXACTLY) {
            measuredWidth = mWidthPixels.toInt()
        }
        if (heightMode != MeasureSpec.EXACTLY) {
            measuredHeight = (mHeightPixels / 3).toInt() + 40
        }
        setMeasuredDimension(measuredWidth, measuredHeight)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        width = w
        height = h
        mViewWidth = width - leftPadding - rightPadding
        mViewHeight = height - topPadding - bottomPadding

        // 修改为支持4级
        elementHeight = mViewHeight / 6 // 从4改为5，为4个level加上间隔
        elementLineHeight = mViewHeight / 6 / 2
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.save()
        canvas.drawColor(Color.WHITE)
        currDrawLeftPoint = leftPadding.toFloat()
        for (i in mDataList.indices) {
            val itemData: SleepChartValueData = mDataList[i]
            val currTimeLong: Int = itemData.timeLong
            val timeScale = currTimeLong * 1.0 / mTotalTime // 当前的时间占比
            val currItemWidth = (mViewWidth * timeScale).toFloat()
            val elementLevel: Int = itemData.elementLevel
            mMainPaint.shader = null
            mLinePaint.shader = null
            val currStatus: Int = itemData.status
            if (0 == i) {
                val roundRectPath = Path()
                val left = currDrawLeftPoint
                val top =
                    (topPadding + elementLevel * elementHeight + elementLevel * elementLineHeight).toFloat()
                val right = left + currItemWidth
                val bottom = top + elementHeight
                val rectf = RectF(left, top, right, bottom)
                roundRectPath.addRoundRect(
                    rectf,
                    roundRectR.toFloat(),
                    roundRectR.toFloat(),
                    Path.Direction.CCW
                )
                //   0,清醒 1:快速眼动 2:浅水 3:深睡
                var startColor = Color.parseColor("#FD886C")
                var endColor = Color.parseColor("#A1B092")
                if (0 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#FD886C"),
                        Color.parseColor("#C49879"),
                        Color.parseColor("#A1A281")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    endColor = Color.parseColor("#A1A281")
                }
                if (1 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#4DBFE7"),
                        Color.parseColor("#48BDC2"),
                        Color.parseColor("#45BC9F")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    endColor = Color.parseColor("#A1A281")
                }
                if (2 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#3DB964"),
                        Color.parseColor("#3FBA7A"),
                        Color.parseColor("#41BA89")
                    )
                    val position = floatArrayOf(0f, 0.5f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    startColor = colors[2]
                }
                if (3 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#A274F6"),
                        Color.parseColor("#7F8DC2"),
                        Color.parseColor("#6E98AA")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        bottom,
                        left,
                        top,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    startColor = colors[2]
                }
                canvas.drawPath(roundRectPath, mMainPaint)
                val nextIndex = i + 1
                val nextItemData: SleepChartValueData = mDataList[nextIndex]
                if (nextItemData != null) {
                    val nextElementLevel: Int = nextItemData.elementLevel
                    val pathLine = Path()
                    val pathTriangle = Path()
                    // 下一个的top
                    val nextTop =
                        topPadding + nextElementLevel * elementHeight + nextElementLevel * elementLineHeight
                    val nextBottom = nextTop + elementHeight
                    if (nextElementLevel < elementLevel) {
                        // 右上
                        pathTriangle.moveTo(right - roundRectR, top)
                        pathTriangle.lineTo(right, top)
                        pathTriangle.lineTo(right, top + roundRectR)
                        pathLine.moveTo(right, top + roundRectR)
                        pathLine.lineTo(right, (nextBottom - roundRectR).toFloat())
                        if (nextItemData.status == 0) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#9EA888")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 1) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#45BC9F")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 2) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#40BA7F")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                    }
                    if (nextElementLevel > elementLevel) {
                        //右下
                        pathTriangle.moveTo(right - roundRectR, bottom)
                        pathTriangle.lineTo(right, bottom - roundRectR)
                        pathTriangle.lineTo(right, bottom)
                        pathLine.moveTo(right, bottom - roundRectR)
                        pathLine.lineTo(right, (nextTop + roundRectR).toFloat())
                        if (nextItemData.status == 2) {
                            val colors = intArrayOf(
                                endColor,
                                Color.parseColor("#5ABF8C"),
                                Color.parseColor("#3FB975")
                            )
                            val position = floatArrayOf(0f, 0.6f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                bottom - roundRectR,
                                right,
                                nextTop.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 3) {
                            val colors = intArrayOf(
                                endColor,
                                Color.parseColor("#5AAA8A"),
                                Color.parseColor("#7990BA")
                            )
                            val position = floatArrayOf(0f, 0.6f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                bottom - roundRectR,
                                right,
                                nextTop.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                    }
                    pathTriangle.close()
                    canvas.drawPath(pathLine, mLinePaint)
                    if (currItemWidth > roundRectR * 2) {
                        canvas.drawPath(pathTriangle, mMainPaint)
                    }
                }
            } else {
                val path = Path()
                val left = currDrawLeftPoint
                val top =
                    (topPadding + elementLevel * elementHeight + elementLevel * elementLineHeight).toFloat()
                val right = left + currItemWidth
                val bottom = top + elementHeight
                val rectf = RectF(left, top, right, bottom)
                path.addRoundRect(
                    rectf,
                    roundRectR.toFloat(),
                    roundRectR.toFloat(),
                    Path.Direction.CCW
                )
                var startColor = Color.parseColor("#6E98AA")
                var endColor = Color.parseColor("#A1B092")
                //   0,清醒 1:快速眼动 2:浅水 3:深睡
                if (0 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#FD886C"),
                        Color.parseColor("#C49879"),
                        Color.parseColor("#A1A281")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    endColor = Color.parseColor("#A1A281")
                }
                if (1 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#4DBFE7"),
                        Color.parseColor("#48BDC2"),
                        Color.parseColor("#45BC9F")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    endColor = Color.parseColor("#45BC9F")
                }
                if (2 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#3DB964"),
                        Color.parseColor("#3FBA7A"),
                        Color.parseColor("#41BA89")
                    )
                    val position = floatArrayOf(0f, 0.5f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        top,
                        left,
                        bottom,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    startColor = colors[2]
                }
                if (3 == currStatus) {
                    val colors = intArrayOf(
                        Color.parseColor("#A274F6"),
                        Color.parseColor("#7F8DC2"),
                        Color.parseColor("#6E98AA")
                    )
                    val position = floatArrayOf(0f, 0.7f, 1.0f)
                    val linearGradient = LinearGradient(
                        left,
                        bottom,
                        left,
                        top,
                        colors,
                        position,
                        Shader.TileMode.CLAMP
                    )
                    mMainPaint.shader = linearGradient
                    startColor = colors[2]
                }
                canvas.drawPath(path, mMainPaint)
                val afterItemData: SleepChartValueData = mDataList[i - 1]
                val afterLevel: Int = afterItemData.elementLevel
                val pathTriangle = Path()
                if (elementLevel > afterLevel) {
                    pathTriangle.moveTo(left + roundRectR, top) //定位到 三角形右角
                    pathTriangle.lineTo(left + 1, top - roundRectR)
                    pathTriangle.lineTo(left + 1, top + roundRectR)
                }
                if (elementLevel < afterLevel) {
                    // 左下角 三角形
                    pathTriangle.moveTo(left + roundRectR, bottom) //定位到 三角形左角
                    pathTriangle.lineTo(left + 1, bottom - roundRectR)
                    pathTriangle.lineTo(left + 1, bottom + roundRectR)
                }
                pathTriangle.close()
                if (currItemWidth > roundRectR * 2) {
                    canvas.drawPath(pathTriangle, mMainPaint)
                }
                if (i < mDataList.size - 1) {
                    val nextItemData: SleepChartValueData = mDataList[i + 1]
                    // 是否有下一个，如果有，则绘制抵达的直线
                    val nextElementLevel: Int = nextItemData.elementLevel
                    val pathLine = Path()
                    val nextPathTriangle = Path()
                    // 下一个的top
                    val nextTop =
                        topPadding + nextElementLevel * elementHeight + nextElementLevel * elementLineHeight
                    val nextBottom = nextTop + elementHeight
                    if (nextElementLevel < elementLevel) {
                        // 右上
                        nextPathTriangle.moveTo(right - roundRectR, top)
                        nextPathTriangle.lineTo(right - 1, top - roundRectR)
                        nextPathTriangle.lineTo(right - 1, top + roundRectR)
                        pathLine.moveTo(right, top + roundRectR)
                        pathLine.lineTo(right, (nextBottom - roundRectR).toFloat())
                        if (nextItemData.status == 0) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#9EA888")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 1) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#45BC9F")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 2) {
                            val colors = intArrayOf(
                                startColor,
                                Color.parseColor("#3FBA79"),
                                Color.parseColor("#40BA7F")
                            )
                            val position = floatArrayOf(0f, 0.5f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                top,
                                right,
                                nextBottom.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                    }
                    if (nextElementLevel > elementLevel) {
                        //右下
                        nextPathTriangle.moveTo(right - roundRectR, bottom)
                        nextPathTriangle.lineTo(right - 1, bottom - roundRectR)
                        nextPathTriangle.lineTo(right - 1, bottom + roundRectR)
                        pathLine.moveTo(right, bottom - roundRectR)
                        pathLine.lineTo(right, (nextTop + roundRectR).toFloat())
                        if (nextItemData.status == 1) {
                            val colors = intArrayOf(
                                endColor,
                                Color.parseColor("#4DBFE7"),
                                Color.parseColor("#3FB975"),
                            )
                            val position = floatArrayOf(0f, 0.6f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                bottom - roundRectR,
                                right,
                                nextTop.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 2) {
                            val colors = intArrayOf(
                                endColor,
                                Color.parseColor("#5ABF8C"),
                                Color.parseColor("#3FB975")
                            )
                            val position = floatArrayOf(0f, 0.6f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                bottom - roundRectR,
                                right,
                                nextTop.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                        if (nextItemData.status == 3) {
                            val colors = intArrayOf(
                                endColor,
                                Color.parseColor("#5AAA8A"),
                                Color.parseColor("#7990BA")
                            )
                            val position = floatArrayOf(0f, 0.6f, 1.0f)
                            val linearGradient = LinearGradient(
                                right,
                                bottom - roundRectR,
                                right,
                                nextTop.toFloat(),
                                colors,
                                position,
                                Shader.TileMode.CLAMP
                            )
                            mLinePaint.shader = linearGradient
                        }
                    }
                    nextPathTriangle.close()
                    canvas.drawPath(pathLine, mLinePaint)
                    if (currItemWidth > roundRectR * 2) {
                        canvas.drawPath(nextPathTriangle, mMainPaint)
                    }
                }
            }
            currDrawLeftPoint = currDrawLeftPoint + currItemWidth
        }
        canvas.restore()
    }

    fun setData(list: List<SleepChartValueData>) {
        mDataList = list
        postInvalidate()
    }

    fun setTotalTime(totalTime: Float) {
        mTotalTime = totalTime
    }
}
